package pab.ui;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

import org.joda.time.LocalDate;
import org.joda.time.Period;
import org.joda.time.PeriodType;

import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;

import pab.core.account.Account;
import pab.core.service.AccountService;
import pab.core.service.ExchangeRate;
import pab.core.transaction.Currency;
import pab.core.transaction.Transaction;
import pab.core.transaction.TransactionType;

public class FutureBudget implements IFutureBudget{

    private List<Transaction> listLatestProjectedTransaction;
    private LocalDate toDate;
    private LocalDate fromDate;
    private ExchangeRate exRate =null;
    private List<Account> listOfAcc= null;
    private Currency curReturn = null;
    public FutureBudget(List<Transaction> listLatestProjectedTransaction, Date toDate, AccountService service, Currency currencyReturn) {
        super();
        this.listLatestProjectedTransaction = listLatestProjectedTransaction;
        this.toDate = new LocalDate(toDate);
        this.fromDate = new LocalDate();
        this.curReturn = currencyReturn;
        this.exRate = service.getExchangeService();
        this.listOfAcc = service.listAccounts();
    }

    //Check Date to get future budge
    public static boolean checkToDate(Date from, Date to){
        boolean result= false;
        LocalDate fromDat = new LocalDate(from);
        LocalDate toDat = new LocalDate(to);
        if(toDat.compareTo(fromDat)== 1 ){
            result = true;
        }
        return result;
    }

    //total balance of accounts - to a currency
    public double totalAmountAccounts(){
        double result = 0.0;
        for(Account a : this.listOfAcc){
            result += exRate.exchangeRate(a.getCurrency(), curReturn)*a.getCurrentBalance();
        }
        return GeneralAuxiliary.round(result, 2) ;
    }

    //Period -->months
    private int monthsBetween(){
        Period period = new Period(this.fromDate, this.toDate, PeriodType.months());
        return period.getMonths();
    }

    //ListFutureTrans
    private List<Transaction> getListFurTrans(TransactionType type){
        LinkedList<Transaction> result = new LinkedList<Transaction>();
        int months = this.monthsBetween();
        for(Transaction t : listLatestProjectedTransaction){
            if(t.getType() == type){
                switch(t.getInterval()) {
                case MONTH:
                    result.addAll(this.repeatePerInterval(t, months, 1));

                case QUARTER:
                    result.addAll(this.repeatePerInterval(t, months, 3));

                case HALF_YEAR:
                    result.addAll(this.repeatePerInterval(t, months, 6));

                case YEAR:
                    result.addAll(this.repeatePerInterval(t, months, 12));

                }

            }
        }
        return result;
    }

    private List<Transaction> repeatePerInterval(Transaction t,int months, int interval){
        LinkedList<Transaction> result = new LinkedList<Transaction>();
        int times = months/interval;
        int steps = 1;
        if(times > 0){
            for(int i=0; i<times; i++){
                LocalDate newDay = this.fromDate.plusMonths(interval * steps);
                XMLGregorianCalendar newD = new XMLGregorianCalendarImpl();
                newD.setYear(newDay.getValue(0));
                newD.setMonth(newDay.getValue(1));
                newD.setDay(newDay.getValue(2));
                Transaction tmp = new Transaction(t.getNumber(),t.getAccount(),t.getType(),t.getAmount(),t.getCurrency(),t.getDesc(),newD,t.getInterval());
                result.add(tmp);
                steps++;
            }
        }
        //	else{}
        return result;
    }


    //ListFutureCreditTrans
    public List<Transaction> getListFurCreditTrans(){
        return this.getListFurTrans(TransactionType.CREDIT);
    }

    //ListFutureCreditTrans
    public List<Transaction> getListFurDebitTrans(){
        return this.getListFurTrans(TransactionType.DEBIT);
    }

    //Sum amount of transition list
    private double sum(List<Transaction> listTrans){
        int result =0;
        if(!listTrans.isEmpty()){
            for(int i=0;i<listTrans.size(); i++){
                Transaction tmp = listTrans.get(i);

                //	System.out.println(exRate.exchangeRate(tmp.getCurrency(), c));
                result += tmp.getAmount()* exRate.exchangeRate(tmp.getCurrency(), curReturn);
            }
        }
        return GeneralAuxiliary.round(result, 2);
    }
    //Compute Credit
    public double amountCredit(){
        return GeneralAuxiliary.round(this.sum(getListFurCreditTrans()),2);
    }
    //Compute Debit
    public double amountDebit(){
        return GeneralAuxiliary.round(this.sum(getListFurDebitTrans()),2);
    }

    public double raiseMoney(){
        return  amountCredit() - amountDebit();
    }

    public double futureBudge(){
        double totalAc = totalAmountAccounts();
        double raiseMoney = raiseMoney();
        return totalAc + raiseMoney;
    }
    /**
     * @param args

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		/*String number, String name, Currency currency, double balance
     * String number, TransactionType type, 
    		double amount, XMLGregorianCalendar date

		XMLGregorianCalendarImpl d1 = new XMLGregorianCalendarImpl();
		d1.setDay(19);
		d1.setMonth(6);
		d1.setYear(2011);
		XMLGregorianCalendarImpl d2 = new XMLGregorianCalendarImpl();
		d2.setDay(31);
		d2.setMonth(6);
		d2.setYear(2011); */
    /*
	Transaction t1 = new Transaction("T001",TransactionType.CREDIT,2000,d1,ProjectedInterval.MONTH);
	Transaction t2 = new Transaction("T001",TransactionType.CREDIT,1000,d1,ProjectedInterval.QUARTER);
	Transaction t3 = new Transaction("T001",TransactionType.DEBIT,300,d1,ProjectedInterval.MONTH);
	Transaction t4 = new Transaction("T001",TransactionType.CREDIT,6000,d2,ProjectedInterval.HALF_YEAR);
	Transaction t5 = new Transaction("T001",TransactionType.DEBIT,1000,d2,ProjectedInterval.YEAR);
	LinkedList<Transaction> list = new LinkedList<Transaction>();
	list.add(t1);
	list.add(t2);
	list.add(t3);
	list.add(t4);
	list.add(t5);
	Date toDate = new Date(2011,12,31);
	FutureBudge fb = new FutureBudge(list, toDate);
//	System.out.println(fb.getListFurCreditTrans());
	System.out.println(fb.getListFurDebitTrans());
	}*/


}
